﻿using IPlugin;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Embedded_Sensor_Cloud
{
    public class PluginManager
    {
        private Dictionary<string, object> plugins;
        public PluginManager()
        {
            plugins = new Dictionary<string, object>();
        }
        public void LoadPlugins()
        {
            //Plugins laden
            if (!Directory.Exists("Plugins"))
            {
                DirectoryInfo dInfo = Directory.CreateDirectory("Plugins");
                if (!dInfo.Exists)
                {
                    Console.WriteLine("Error: Plugins Verzeichnis wurde nicht gefunden und konnte auch nicht neu angelegt werden!\n" +
                        "Server muss beendet werden. Beliebige Taste drücken...");
                    Console.Read();
                    System.Environment.Exit(0);
                }
            }
            Console.WriteLine("Loaded Plugins:\n" + "===============\n" + "Name and Version of Plugins");
            foreach (string plugin in Directory.GetDirectories("Plugins"))
            {
                Assembly ass = Assembly.LoadFrom(plugin + "/plugin.dll");
                Type type = ass.GetType("Plugin.Plugin");
                IPlugin.IPlugin ip = (IPlugin.IPlugin)Activator.CreateInstance(type);
                plugins.Add(ip.Name, ip);
                Console.WriteLine(ip.Name + "   " + ip.Version);
            }
            Console.WriteLine("===============");
        }
        public Response HandleRequest(Request req)
        {
            string[] separatedBlocks = req.ReqUrl.Path.Split('/');
            string firstBlock = separatedBlocks[1];
            //Console.WriteLine("First Block: '" + firstBlock + "'");

            /* Erster Block gibt Pluginnamen an, welches aufgerufen werden soll
             * Gibt es keinen ersten Block, ist kein Pfad in der Url angegeben worden = default Seite anzeigen
             * Gibt es kein Plugin mit dem angegeben Namen im ersten Block, so wird als Standard 
             * das GetFile Plugin aufgerufen (insofern es als Plugin geladen wurde)
             */

            if (plugins.ContainsKey(firstBlock))
            {
                IPlugin.IPlugin pluginObject = (IPlugin.IPlugin)plugins[firstBlock];
                IPlugin.Response resp = pluginObject.ExecutePlugin(req);
                return resp;
            }
            else
            {
                //Standard Plugin ausfuehren (GetFile)
                if (plugins.ContainsKey("GetFile"))
                {
                    IPlugin.IPlugin pluginObject = (IPlugin.IPlugin)plugins["GetFile"];
                    IPlugin.Response resp = pluginObject.ExecutePlugin(req);
                    return resp;
                }
                else
                {
                    /* Kein Plugin gefunden, welches Request bearbeiten kann
                     * Dies darf nicht vorkommen, da StandardPlugin GetFile 
                     * nicht geloescht werden darf vom Benutzer. 
                     */
                    IPlugin.Response resp = new IPlugin.Response(req.getSocket());
                    resp.StatusCode = 500;
                    resp.StatusText = "Internal Server Error";
                    resp.ContentType = "text/html";
                    resp.Data = "<html><body><h1>Error 500: Internal Server Error</h1>" +
                        "<p>Das Standard-Plugin konnte nicht aufgerufen werden.</p></body></html>";
                    return resp;
                }
            }

        }
    }
}
